Overview

  • Hour 1
    • Nested Loops
    • Strings
  • Hour 2
    • Functions
  • Hour 3
    • Graded Lab

Nested Loop

  • We can have loops inside of loops

In [49]:
# This program displays a rectangular pattern of asterisks

width = 2
height = 2

for h in range(height):
    for w in range(width):
        print ("*"),    
    print("")


* * 
* * 

In [52]:
# This program displays a triangle pattern of asterisks
# *
# * *
# * * *

height = 10

for h in range(height):
    for w in range(h + 1):
        print ("*"),    
    print("")


* * * * * 
* * * * * 
* * * * * 
* * * * * 
* * * * * 

In [62]:
height = 10

for h in range(height):
    print ("*" * (h + 1))


*
**
***
****
*****
******
*******
********
*********
**********

Strings Operations

  • Strings are a sequence of characters delimited by quotation marks.
    • This means we should be able to get the individual characters or sub-sequences
    • Which in turn means, we can perform operations on the characters or sub-sequences

Indexing

  • Individual characters in strings can be identified using an index.
  • This is done by adding square brackets to the end of a string (value or variable)
  • Indexes start from 0 (It's a computer science thing.)

  • We can get a copy of a character from a string

In [63]:
"Hello, I wish to register a complaint."[0] # This should be H


Out[63]:
'H'

In [67]:
opening = "Hello, I wish to register a complaint."
opening[37]


Out[67]:
'.'

In [65]:
len("Hello, I wish to register a complaint.")


Out[65]:
38

In [66]:
"Hello, I wish to register a complaint."[37]


Out[66]:
'.'

Negative Indexes

  • We can use negative indexes to access the characters starting at the end of a string
    • Easier than figuring out the index of the last character

In [68]:
"Hello, I wish to register a complaint."[-1] # This should be .


Out[68]:
'.'

In [70]:
"Hello, I wish to register a complaint."[-15]


Out[70]:
'e'

In [72]:
opening = "Hello, I wish to register a complaint."
opening[-38]


Out[72]:
'H'

IndexError Exceptions

  • An IndexError exception is thrown when you use an array index is out of range

Exceptions

  • An Exception is an object or data structure that is passed back to a calling context when there is a problem

    • Not meant to be used in normal operation
  • If you don't want an exception to cause your program to crash, you can handle them in your code using try/except blocks

try:
    statement
    statement
except ExceptionName:
    statement
    statement

Inside the try block are the statement that might throw an exception.

The statements in the except block are run when an exception of type ExceptionName is thrown by the try block.

We'll come back to this later in the course.


In [74]:
opening = "Hello, I wish to register a complaint."

try:
    opening[100]
except IndexError:
    print("Index out of range for string")


Index out of range for string

In [78]:
user_input = raw_input("> ")

try:
    user_input = int(user_input)
except ValueError:
    print("Can't do it. Not a number")


#user_input += 1
#print(user_input)


> string
Can't do it. Not a number

Iterating Over a String

  • To access every character in a string, we can use a loop

In [79]:
name = "Monty"
for character in name:
    print(character)


M
o
n
t
y

In [81]:
name ="Monty"
index = 0
while index < len(name):
    print(name[index])
    index += 1


M
o
n
t
y

In [ ]:
name ="Monty"
index = 0

while index < 6:
    print(name[index])
    index += 1

String Slicing

  • A slice is a span of items that are taken from a sequence.
  • A slicing expression can be used to select a range of characters from a string.
  • General format of a string slice:
      string[ start : end : step]

This is similar to the range function from last week.


In [86]:
"Hello, I wish to register a complaint."[10:20:2]


Out[86]:
'iht e'

Testing, Searching, and Manipulating Strings

  • Python provides a number of operators and methods for testing strings, searching the contents of strings, and getting modified copies of strings.

Testing with in and not in

  • Evaluates to a Boolean
  • General formats
string1 in string2

string1 not in string2

In [87]:
knights = "Arthur Lancelot Robin Bedevere Galahad"

if "Arthur" in knights:
    print("Arthur is a knight")
else:
    print("Arthur is not a knight")

if "Graham" not in knights:
    print("Graham is not a knight")
else:
    print("Graham is a knight")


Arthur is a knight
Graham is not a knight

String Methods

  • A method is a function that belongs to an object. (Strings are objects.)
  • General form
   string.method(arguments)

There are a lot of useful string methods. You'll learn them over time. Here are a few to get you started.


In [91]:
"Hello, I wish to register a complaint.".isdigit()


Out[91]:
False

In [ ]:
# Write a function to check that a password is strong enough


In [93]:
"Hello, I wish to register a complaint.".upper()


Out[93]:
'HELLO, I WISH TO REGISTER A COMPLAINT.'

Strings are Immutable

  • A data structure that is immutable cannot be changed after it is created.

Wait, what?

Yes, all those strings that we were concatenating or appending were busy making copies.


In [ ]:
knights = "Lancelot"
knights += " Robin"
knights

In [ ]:


In [94]:
"Hello, I wish to register a complaint.".find("wish")


Out[94]:
9

In [97]:
"Hello, I wish to register a complaint."[9:13]


Out[97]:
'wish'

In [99]:
"Hello, I wish to register a complaint.".replace("wish", "demand")


Out[99]:
'Hello, I demand to register a complaint.'

Splitting a String


In [100]:
knight_string = "Arthur Lancelot Robin Bedevere Galahad"
knight_list = knight_string.split()

knight_list


Out[100]:
['Arthur', 'Lancelot', 'Robin', 'Bedevere', 'Galahad']

In [102]:
date_string = "15/10/2015"
date_string.split("/")


Out[102]:
['15', '10', '2015']

Functions

  • A function is a way to group together lines of code.
  • Useful for doing the same task in different places.
  • Makes the code easier to read.
  • Avoids repeating code.
def function_name():
    statement
    statement
    statement
  • A function has the following parts.
    • A name
    • Parameters (inputs)
    • Optionally, return values (outputs)

Functions are either a void function or a value-returning function.

Defining and Calling a Void Function

  • The code for a function is known as a function definition.
  • To cause a function to run, you write a statement that calls it.

  • General form for definition

    def function_name():
      statement
      statement
  • General form for call

function_name()

In [104]:
# This program demonstrates a function
# First we define a function named "message"

def message():
    print("I am Arthur")
    print ("King of the Britons")

# Call the message function
message()


I am Arthur
King of the Britons

Function Names

  • Not a Python keyword
  • No spaces
  • First character must be uppercase letter, lowercase letter, or underscore (_)
  • Subsequent characters can be the above, plus digits 0-9
  • Case sensitive

Functions Calling Functions

See the visualization


In [105]:
def wrapped_message():
    print("I have a message for you")
    message()
    print("Good bye!")

def message():
    print("I am Arthur")
    print ("King of the Britons")

wrapped_message()


I have a message for you
I am Arthur
King of the Britons
Good bye!

Indentation

  • In Python, indentation is used to indicate blocks
  • Blocks are lines of code that execute as a group.
  • Blocks are contexts.
  • Python best practice is to indent using 4 spaces

Local Variables

  • Variables have scope, or visibility to other parts of the program.
  • We have mostly been using the top level or global scope.
  • Functions are a new scope.
  • A local variable is a variable that has been created inside a function. It is not visible outside the function.
  • Functions cannot see each other's local variables.

The visibility or scope of a variable is what allows us to have variables that have the same name, but point to different data in different contexts.


In [107]:
def blue_jays():
    runs = 6
    print ("The Blue Jays scored {0} runs").format(runs)
    rangers()

def rangers():
    runs = 3
    print("The Rangers scored " + str(runs) + " runs")

runs = 9
print(runs)
blue_jays()
print(runs)

print(runs)


9
The Blue Jays scored 6 runs
The Rangers scored 3 runs
9
9

Passing Data to Functions

  • An argument is data passed in to a function when it is called.
  • A parameter is a variable that receives the data. It is named when the code is written.

See Online Python Tutor visualization


In [108]:
def greet(name):
    # This printing style is legal in Python 2, but
    # discouraged in Python 3
    print("Hello %s!") % name

knight = "Sir Bedevere"
greet(knight)


Hello Sir Bedevere!

Passing Multiple Arguments

  • Arguments must be passed into functions in the same order as the parameters in the function definition.

In [110]:
def outrank(knight1, knight2):
    print(knight1 + " outranks " + knight2)

outrank("Arthur", "Galahad")


Galahad outranks Arthur

Making Changes to Parameters

  • Python is a "call by value" language, which means the value is passed into functions

Aside

  • The alternative is "call by reference", which means a pointer to the data structure is passed into functions.
  • C/C++ is a call by reference language.

In [111]:
def change_me(arg):
    print("change_me() is changing the value")
    arg = 0
    print("Now the value is {0}").format(arg)

value = "Lancelot"
print("The value is " + value)
change_me(value)
print("Back in main the value is " + value)


The value is Lancelot
change_me() is changing the value
Now the value is 0
Back in main the value is Lancelot

Value-Returning Functions

  • Pass data back to the calling context
  • Uses the return keyword
  • Can return a single value
  • Can return multiple values using a data structure, e.g. list, tuple, or dictionary

In [114]:
def holy_hand_grenade(tick):
    output = ""
    
    if tick == 1:
        output = "Keepest going"
    elif tick == 2:
        output = "Nor either count thou two, excepting that thou then proceed to three"
    elif tick == 3:
        output = "Lobbest thou thy Holy Hand Grenade of Antioch towards thou foe"
    elif tick == 4:
        output = "Four shalt thou not count"
    elif tick == 5:
        output = "Five is right out"
    
    return output

instruction = holy_hand_grenade(3)

print(instruction[5:10])


st th

In [ ]:

Let's Practice


In [120]:
# Turn this code into a function

def what_to_wear(temperature):
    output = ""
    
    if (temperature < 15):
        output = "Wear a coat."
    
    return output

what_to_wear(8)


Out[120]:
'Wear a coat.'

In [ ]:
# Write a function to sum two values

def sum(number1, number2):